package engine.control
{	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	
	import newx.StageInfo;
	import newx.com.ResManager;
	import newx.com.control.list.NxList;
	import newx.com.control.list.NxListEvent;
	import newx.utils.debug.IO;
	
	/** 纯AS互动菜单   			version 1.0
	 * 				
	 * 	@author hanjy				
	 * 
	 * 			该工具类在一个swf播放器中始终只存在一个实例
	 *  
	 *  通用设置（使用下面的设置的时候会改变全局的显示效果）
	 * 
	 * 			作用							方法
	 * 		1.设置背景颜色				MenuList.setBgColor		(新的十六进制颜色色值);
	 * 		2.设置边框线条颜色			MenuList.setBorderColor	(新的十六进制颜色色值);
	 * 		3.设置文本颜色				MenuList.setTextColor		(新的十六进制颜色色值);
	 * 		4.设置背景透明度			MenuList.setBgAlpha		(新的透明度值);
	 * 		5.设置背景图片				MenuList.setBgImageUrl		(背景地址);
	 * 		6.设置缩放区域				MenuList.setBgScale9Grid	(缩放区域);  				（当背景设置正确后才能选择使用）
	 * 
	 * 		finale 隐藏提示框			MenuList.hide();
	 * 
	 * 		*******   		注意 		********
	 * 			1.若中途需要修改以上的2个或2个以上的属性，建议直接重新初始化该类 即调用 MenuList.Init(...argc)
	 * 			2.设置背景图片且成功加载后，自动绘制的背景颜色及线条将不存在.其他情况下，都会使用定义的配置颜色进行绘制背景
	 * 			3.更换或初次设置图片的时候，不会立即显示新的背景图片，当再次调用AsToolTip.ShowInfo(...argc)的时候才会显示
	 * 		*******
	 * 
	 *  使用方法有2种
	 * 
	 * 	方法一使用步骤
	 * 		1.在主文档类中先初始化该类 即直接调用 		MenuList.Init(...argc);
	 * 		2.在要显示悬浮提示的时候调用				MenuList.ShowInfo(...argc);
	 * 
	 *  方法二
	 * 		直接使用  MenuList.ShowInfo(...argc) ，此方法下的悬浮框将使用默认的颜色配置
	 */	
	public class MenuList extends Sprite
	{		
		private static var hasConstruct		:Boolean		=	false;
		private static var notePanel			:MenuList;
		private static var _stage				:DisplayObjectContainer;
		private static var bgColor			:uint			=	0x000000;	//背景颜色
		private static var borderColor		:uint			=	0xccff00;	//线条颜色
		private static var textColor			:uint			=	0xf9f9f9;	//字体颜色
		private static var bgAlpha			:Number			=	0.7;		//背景透明度
		private static var bgImageData		:DisplayObject	=	null;
		private static var bgScale9Grid		:Rectangle		=	null;
		
		private static var bgSkinStr	:String		=	"";
		private static var itemSkinStr	:String		=	"";
		
		private var itemList	:NxList;
		private var itemListBG : MovieClip;
		
		private var bg			:Sprite		=	new Sprite;
		private var checkTxt	:TextField	=	new TextField();
		private var MaxWidth	:int		=	0;
		private var MinWidth	:int		=	80;
		private var rate		:int		=	5;
		
		private var rx			:int		=	0;
		private var dy			:int		=	0;
		
		private var _callBack	:Function	=	null;
		private var _clickData	:Object	=	null;
		
		/** 初始化基本设置，一般在主类最前面使用
		 * 
		 * @param _client			显示对象的载体
		 * @param _bgColor			背景颜色
		 * @param _borderColor		边框线条颜色
		 * 
		 * @param _bgImageUrl		背景图片地址（可以是swf）,如果不设置，则背景为纯色绘制底图
		 * @param _bgScale9Grid		如果设置了正确的背景地址（能正确访问到的图片或者swf地址），
		 * 							那么在背景加载完成后，则自动按这个rectangle配置缩放区域，不设置值的时候将按默认的值进行缩放
		 * 							默认值为大小是 50*20 的源文件，缩放区域是 (5,5,40,10);
		 * @param _textColor		文字颜色
		 * @param _bgAlpha			透明度
		 * 
		 */		
		public static function Init(	_client:DisplayObjectContainer,bgSkin:String="",itemSkin:String="",_textColor:uint = 0xf9f9f9,	_bgAlpha:Number = 0.7	):void
		{
			MenuList.setBgAlpha			(_bgAlpha);
			
			if(!MenuList._stage)
			{
				if(_client.stage)
				{
					if(bgSkin)
						bgSkinStr	=	bgSkin;
					if(itemSkin)
						itemSkinStr	=	itemSkin;
					MenuList.notePanel		=	new MenuList();
					MenuList._stage		=	_client;
//					MenuList._stage.addChild	(MenuList.notePanel);
					//StageInfo.stage.addEventListener(MouseEvent.MOUSE_UP,hide);
				}
				else
				{
					throw new Error("初始化失败, " + _client + " 不在显示列表中，请先将 " +
						_client + " 添加到显示列表中!");
				}
			}
		}
		
		/** 设置文本的颜色
		 * 
		 * @param c				新的十六进制颜色色值
		 * 
		 */		
		public static function setTextColor(c:uint):void
		{
			MenuList.textColor				=	c;
		}
		
		/** 设置背景透明度
		 * 
		 * @param c				新的十六进制颜色色值
		 * 
		 */		
		public static function setBgAlpha(c:Number):void
		{
			c								=	Math.abs(c);
			if(c > 1)
			{
				c							=	(c % 101) / 100;
			}
			MenuList.bgAlpha				=	c;
		}
		
		/** 将目标绑定鼠标滑过和离开的事件显示信息(适用于提示信息固定不变的)
		 * 
		 * @param target				包绑定的对象
		 * @param content				要显示的提示信息
		 * 
		 */		
		public static function BindMenu(target:DisplayObject,contentArr:Array,callBack:Function=null):void
		{
			
			var onDown		:Function	=	function(e1:MouseEvent):void
			{
				MenuList.ShowMenu(contentArr,callBack);
			}
			target.addEventListener(MouseEvent.MOUSE_DOWN,						onDown);
			
		}
		
		/** 静态方法 显示提示信息
		 * 
		 * @param contentArr		baseitem 数组
		 * @param followMouse		是否跟随鼠标，如果不跟随鼠标，则必须设置stagePosition参数
		 * @param stagePosition		全局（舞台）坐标点  (此参数只在followMouse设置为false的时候才有效)
		 * 
		 */		
		public static function ShowInfo(contentArr:Array,callBack:Function=null,stagePosition:Point = null):void
		{
			if(!MenuList._stage)
			{	IO.traceLog("    提示信息:",contentArr.length);
				IO.traceLog("还没对 MenuList 进行初始化，请先调用 MenuList.Init(...argc) 对MenuList进行初始化");
				return;
			}
			MenuList.notePanel.showText(contentArr,callBack,stagePosition);
		}
		
		
		/**
		 * 静态方法 显示提示信息 传入字符串数组
		 * @param contentArr	字符串数组
		 * @param callBack
		 * @param clickData
		 * @param stagePosition
		 * 
		 */
		public static function ShowMenu(contentArr:Array,callBack:Function=null,clickData:Object=null,stagePosition:Point = null,bgSkin:String="",itemSkin:String=""):void
		{
			if(!MenuList._stage)
			{	IO.traceLog("    提示信息:",contentArr.length);
				IO.traceLog("还没对 MenuList 进行初始化，请先调用 MenuList.Init(...argc) 对MenuList进行初始化");
				return;
			}
			var meneContent:Array = new Array();
			for(var i:int=0;i<contentArr.length;i++)
			{
				notePanel.checkTxt.htmlText	=	contentArr[i].toString();
				
				if(notePanel.checkTxt.textWidth > notePanel.MaxWidth){
					notePanel.MaxWidth	=	notePanel.checkTxt.textWidth+4
				}
				meneContent.push({label:contentArr[i].toString(),data:i});
			}
			MenuList.notePanel.showText(meneContent,callBack,clickData,stagePosition,bgSkin,itemSkin);
		}
		
		/**
		 * 静态方法 显示提示信息 传入object数组
		 * @param contentArr	object数组
		 * @param callBack
		 * @param clickData
		 * @param stagePosition
		 * 
		 */
		public static function ShowIconMenu(contentArr:Array,callBack:Function=null,clickData:Object=null,stagePosition:Point = null,bgSkin:String="",itemSkin:String=""):void
		{
			if(!MenuList._stage)
			{
				return;
			}
			var meneContent:Array = new Array();
			for(var i:int=0;i<contentArr.length;i++)
			{
				meneContent.push(new BaseItem(contentArr[i]["name"],null,null,contentArr[i].icon));
			}
			MenuList.notePanel.showText(meneContent,callBack,clickData,stagePosition,bgSkin,itemSkin);
		}
		
		/** 隐藏 AsMenuList **/		
		public static function hide(...rest):void
		{
			if(MenuList.notePanel)
			{
				MenuList.notePanel.hideText();
				MenuList.notePanel.MaxWidth	=	0;
			}
		}
		
		public function MenuList()
		{
			if(MenuList._stage || MenuList.hasConstruct)
			{
				throw new Error(" ------- MenuList 已经在内存中存在，不能重复构建 MenuList -------");
				return;
			}
			
			MenuList.hasConstruct	=	true;
//			this.addEventListener(Event.ADDED_TO_STAGE,		init);
			init();
//			this.addEventListener(Event.REMOVED_FROM_STAGE,	deleteEvent);
		}
		
		/** 重绘基本界面
		 * 
		 * @param argc			参数暂时不处理
		 * 
		 */				
		private final function init(...argc):void
		{
//			itemList = new NxList(80,10,false,null,bgSkinStr,itemSkinStr);//25,
			
			itemListBG = ResManager.newResClass( bgSkinStr ) as MovieClip;
			addChild( itemListBG );
			itemListBG.mouseChildren = itemListBG.mouseEnabled =false;
			
			itemListBG.y -= 4;
			
			itemList		=	new NxList();
			checkTxt		=	new TextField();
			checkTxt.htmlText	=	"";
			itemList.width	=	80;
//			itemList.height=10;
			itemList.itemSkin = itemSkinStr;
			itemList.vScrollSkin = "vScrol_1";
			itemList.hScrollSkin = "vScrol_2";
			itemList.dataProvider=[];
			itemList.itemAlign="center";
			
//			itemList.btnLeft	=	1;
//			itemList.btnTop	=	1;
//			itemList.show(this);
			this.addChild(itemList);
			
//			itemList.removeScroll();
			addEvent();
		}
		
//		private final function deleteEvent(e:Event):void
//		{
//			MenuList._stage		=	null;
//			MenuList.hasConstruct	=	false;
//			MenuList.bgImageData	=	null;
//			MenuList.bgScale9Grid	=	null;
//			//			this.removeEventListener(Event.ENTER_FRAME,		effOut);
//		}
		private function onHideList(e:MouseEvent):void
		{
			if(notePanel.contains(e.target as DisplayObject))return;
			hide(e);
			itemList.currentSelect = -1;
		}
		/** 获取当前提示框的宽度
		 * 
		 * @return 
		 * 
		 */		
		public static function getWidth():Number
		{
			if(notePanel)
			{
				return notePanel.width;
			}
			return 0;
		}
		
		/** 获取当前提示框的高度
		 * 
		 * @return 
		 * 
		 */		
		public static function getHeight():Number
		{
			if(notePanel)
			{
				return notePanel.height;
			}
			return 0;
		}
		
		/** 移动提示框的位置
		 * 
		 * @param X
		 * @param Y
		 * 
		 */		
		public static function moveTo(X:Number,Y:Number):void
		{
			if(notePanel)
			{
				notePanel.x					=	X;
				notePanel.y					=	Y;
			}
		}
		
		private function onClickItem(e:NxListEvent):void
		{
			dispatchEvent(e);
			hide(e);
		}
		
		/** 实例显示提示信息的接口
		 * 
		 * @param content			信息内容
		 * @param stagePosition		全局（舞台）坐标点 
		 * 
		 */	
		public final function showText(strList:Array,callBack:Function=null,clickData:Object=null,stagePosition:Point = null,bgSkin:String="",itemSkin:String=""):void
		{
			if(strList.length==0)
			{
				if(this.parent)
					this.parent.removeChild(this);
				return;
			}
			
//			if(bgSkin)
//			{
//				itemList.backSkinName	=	bgSkin;
//			}else{
//				itemList.backSkinName	=	bgSkinStr;
//			}
//			if(itemSkin)
//			{
//				itemList.btnSkinName	=	itemSkin;
//			}else{
//				itemList.btnSkinName	=	itemSkinStr;
//			}
				
			_callBack	=	callBack;
			_clickData	=	clickData;
//			itemList.listData = null;
//			itemList.listData = strList;
			itemList.dataProvider=strList;
			itemList.currentSelect = -1;
			if(MaxWidth > MinWidth){
				itemList.width	=	MaxWidth;
			}else{
				itemList.width	=	MinWidth;
			}
			itemList.showCount=strList.length;
			
			this.bg.alpha			=	MenuList.bgAlpha;
			MenuList._stage.addChild	(MenuList.notePanel);
			
			//			this.removeEventListener(Event.ENTER_FRAME,		effOut);
			
			this.alpha			=	1;
			
			this.parent.setChildIndex(this,this.parent.numChildren - 1);
			
			itemListBG.width = itemList.width;
			itemListBG.height = itemList.height + 8;
			
			if(!stagePosition)
			{
				setPosition();
			}
			else
			{
				this.x			=	stagePosition.x + 3;
				this.y			=	stagePosition.y + 3;
			}
			//setPosition();
			if(_stage)
				_stage.addEventListener(MouseEvent.MOUSE_DOWN, onHideList);
			addEvent();
		}
		/**
		 * 设定默认位置 
		 * 
		 */
		private final function setPosition():void
		{	
			this.x					=	_stage.mouseX + 8;
			this.y					=	_stage.mouseY + 7;
			
			var gameWidth:Number	=	_stage.stage.stageWidth > StageInfo.rootMaxW ? StageInfo.rootMaxW : _stage.stage.stageWidth;
			var gameHeight:Number	=	_stage.stage.stageHeight > StageInfo.rootMaxH? StageInfo.rootMaxH : _stage.stage.stageHeight;
			//右面超出
			if(_stage.stage.mouseX + itemList.width > gameWidth)
			{
				this.x -= itemList.width;
			}
			//底部超出
			if(_stage.stage.mouseY + itemList.height > gameHeight)
			{
				this.y -= itemList.height;
			}
		}
		
		private function addEvent():void
		{
			if(!itemList.hasEventListener(NxListEvent.LIST_CLICK))
			{
				itemList.addEventListener(NxListEvent.LIST_CLICK, function(e:NxListEvent):void
				{
					if(_callBack!=null)
					{
						_callBack.call(this,e.id,_clickData);
					}
					hide(e);
					e.currentTarget.removeEventListener(e.type, arguments.callee);
				});
			}
			
		}
		
		/** @private 实例隐藏的方法 **/
		public final function hideText():void
		{
			if(this.parent)
				this.parent.removeChild(this);
			StageInfo.stage.removeEventListener(MouseEvent.MOUSE_DOWN, onHideList);
		}
		
		public static function isVisible():Boolean
		{
			return MenuList.notePanel.checkVisible();
		}
		public function checkVisible():Boolean
		{
			return this.parent != null;
		}
	}
}